import { useAtomValue } from "jotai";
import { Button, Popconfirm, Popover } from "antd";
import { useCallback, useRef, type PropsWithChildren } from "react";
import { deleteAlarm, getAlarmInfo } from "@/lib/api/alarm";
import useFetch from "@/lib/hooks/useFetch";
import { tokenAtom } from "@/store/user";
import AlertIcon from "@/assets/icons/alert.svg?jsx";
import XCircleIcon from "@/assets/icons/x-circle.svg?jsx";
import type { IDeviceAlarmLog } from "@/lib/types";
import useOnMounted from "@/lib/hooks/useOnMounted";
import { formatTime } from "@/lib/utils/time";
import { useMessage } from "@/providers/AntdMessageProvider";
import getRequestErrorMessage from "@/lib/utils/getRequestErrorMessage";

export default function Alarms() {
  const token = useAtomValue(tokenAtom);
  const {
    data,
    refetch: loadAlarmInfo,
    cancel: cancelLoadAlarmInfo,
  } = useFetch({
    fetchFn: (signal) =>
      getAlarmInfo(token, signal).then((res) => {
        if (res.code !== 200) {
          throw res;
        }
        return res.data;
      }),
  });

  const timerRef = useRef<Timer>();
  const handleLoadAlarmInfo = useCallback(() => {
    loadAlarmInfo();
    timerRef.current = setTimeout(handleLoadAlarmInfo, 5000);
  }, [loadAlarmInfo]);

  const reload = useCallback(() => {
    timerRef.current && clearTimeout(timerRef.current);
    cancelLoadAlarmInfo();
    handleLoadAlarmInfo();
  }, [handleLoadAlarmInfo, cancelLoadAlarmInfo]);

  useOnMounted(() => {
    handleLoadAlarmInfo();
    return () => {
      cancelLoadAlarmInfo();
      timerRef.current && clearTimeout(timerRef.current);
    };
  });

  return (
    <>
      <Alerts data={data?.alarms || []} reload={reload}>
        <AlertIcon className="text-red-500" />
        <sub>{data?.alarms.length}</sub>
      </Alerts>
      <Alerts data={data?.warnings || []} reload={reload}>
        <AlertIcon className="text-yellow-500" />
        <sub>{data?.warnings.length}</sub>
      </Alerts>
    </>
  );
}

type AlertsProps = PropsWithChildren<{
  data: IDeviceAlarmLog[];
  reload: () => void;
}>;

function Alerts(props: AlertsProps) {
  const { children, data, reload } = props;
  return (
    <Popover
      content={<ContentTable data={data} reload={reload} />}
      trigger={["click"]}
      placement="bottom"
      arrow={false}
    >
      <div className="flex h-full items-center">
        <Button type="text" size="small">
          {children}
        </Button>
      </div>
    </Popover>
  );
}

function ContentTable({
  data,
  reload,
}: {
  data: IDeviceAlarmLog[];
  reload: () => void;
}) {
  return (
    <div className="w-[400px] px-8 py-4">
      <table className="w-full text-left">
        <colgroup>
          <col />
          <col />
          <col />
          <col width={30} />
        </colgroup>
        <thead>
          <tr>
            <th>设备</th>
            <th>报警</th>
            <th>时间</th>
            <th></th>
          </tr>
        </thead>
        <tbody>
          {data.map((alarm) => (
            <AlarmItem alarm={alarm} key={alarm.alarmName} reload={reload} />
          ))}
        </tbody>
      </table>
    </div>
  );
}

function AlarmItem({
  alarm,
  reload,
}: {
  alarm: IDeviceAlarmLog;
  reload: () => void;
}) {
  const token = useAtomValue(tokenAtom);
  const message = useMessage();
  const { isLoading: isDeleteLoading, refetch: handleDeleteAlarm } = useFetch({
    fetchFn: (data: Parameters<typeof deleteAlarm>[0]) =>
      deleteAlarm(data, token).then((res) => {
        if (res.code !== 200) {
          throw res;
        }
      }),
    onError(error) {
      message.error(getRequestErrorMessage(error));
    },
    onSuccess() {
      reload();
      message.success("删除成功！");
    },
  });
  return (
    <tr>
      <td>{alarm.deviceName}</td>
      <td>{alarm.alarmName}</td>
      <td>{formatTime(alarm.alarmTime, "HH:mm:ss")}</td>
      <td>
        <Popconfirm
          title="确定删除吗？"
          disabled={isDeleteLoading}
          onConfirm={() =>
            handleDeleteAlarm({
              deviceId: alarm.deviceId,
              alarmName: alarm.alarmName,
            })
          }
        >
          <Button type="text" loading={isDeleteLoading}>
            <XCircleIcon className="size-5 text-zinc-600" />
          </Button>
        </Popconfirm>
      </td>
    </tr>
  );
}
